package nl.Viewer.SerializedObjects;

import nl.Viewer.Sessions.Communication.ParameterException;

/**
 * Client-side deserialization and partial implementation of a visualization parameter
 * 
 * @author Jeroen Verschuur
 * 
 */

public class Parameter {
   protected String  parameterName;

   protected Object  parameterValue = null;

   protected boolean isModified     = false;

   public static enum ParameterType {
      INT, STRING, DOUBLE, BOOLEAN
   }

   protected ParameterType parameterType              = ParameterType.INT;
   protected boolean       isTuple                    = false;
   protected boolean       isUserViewable             = true;
   protected boolean       isUserModifiable           = true;
   protected int           parameterLength            = 1;
   protected boolean       requiredForSynchronization = false;

   public Parameter( String parameterName, ParameterType parameterType, boolean isTuple, int parameterLength,
         Object parameterValue, boolean isUserViewable, boolean isUserModifiable, boolean requiredForSynchronization )
         throws ParameterException {
      super();
      this.parameterName = parameterName;

      this.parameterType = parameterType;
      this.isTuple = isTuple;
      this.parameterLength = parameterLength;

      this.setParameterValue( parameterValue );

      this.isUserViewable = isUserViewable;
      this.isUserModifiable = isUserModifiable;
      this.requiredForSynchronization = requiredForSynchronization;
   }

   public String toString() {
      return "Parameter: " + parameterName + ": " + getPythonRepresentation();
   }

   public boolean equals( Object p ) {
      if( p instanceof Parameter == false )
         return false;

      Parameter param = (Parameter)p;
      // check the parameterName, type, isTuple, isUserViewable, isUserModifiable, parameterLength,
      // requiredForSynchronization
      if( param.parameterName.equals( this.parameterName ) == false
         || param.parameterType.equals( this.parameterType ) == false || param.isTuple != this.isTuple
         || param.isUserModifiable != this.isUserModifiable || param.isUserViewable != this.isUserViewable
         || param.parameterLength != this.parameterLength
         || param.requiredForSynchronization != this.requiredForSynchronization )
         return false;

      // everything matched
      return true;
   }

   public static String getPythonRepresentation( Object input ) {
      if( input == null )
         return "None";
      // if we are dealing with arrays, loop through all elements and print them
      // between [ ]
      if( input.getClass() == String[].class || input.getClass() == Integer[].class
         || input.getClass() == Float[].class || input.getClass() == Double[].class
         || input.getClass() == Object[].class ) {
         Object[] s = (Object[])input;
         String r = "[";
         for( int i = 0; i < s.length; i++ ) {
            if( i > 0 ) {
               r += ", ";
            }
            r += getPythonRepresentation( s[i] );
         }
         return r += "]";
      } else if( input.getClass() == int[].class ) {
         int[] s = (int[])input;
         String r = "[";
         for( int i = 0; i < s.length; i++ ) {
            if( i > 0 ) {
               r += ", ";
            }
            r += getPythonRepresentation( s[i] );
         }
         return r += "]";
      } else if( input.getClass() == double[].class ) {
         double[] s = (double[])input;
         String r = "[";
         for( int i = 0; i < s.length; i++ ) {
            if( i > 0 ) {
               r += ", ";
            }
            r += getPythonRepresentation( s[i] );
         }
         return r += "]";
      } else if( input.getClass() == float[].class ) {
         float[] s = (float[])input;
         String r = "[";
         for( int i = 0; i < s.length; i++ ) {
            if( i > 0 ) {
               r += ", ";
            }
            r += getPythonRepresentation( s[i] );
         }
         return r += "]";
      } else if( input.getClass() == String.class ) { // when dealing with
         // strings, make sure to
         // put '' around the
         // string
         return "'" + (String)input + "'";
      } else {
         // single integer, float, double, etc objects (but not String)
         return input.toString();
      }
   }

   public void setModified( boolean isModified ) {
      this.isModified = isModified;
   }

   public boolean isModified() {
      return isModified;
   }

   public synchronized void setParameterValue( Object value ) {
      parameterValue = value;
      // notifyParameterChangeListeners();
   }

   public synchronized String getPythonRepresentation() {
      return getPythonRepresentation( parameterValue );
   }

   public String getParameterName() {
      return parameterName;
   }

   public synchronized Object getParameterValue() {
      return parameterValue;
   }

   public ParameterType getParameterType() {
      return parameterType;
   }

   public int getParameterLength() {
      return parameterLength;
   }

   public boolean isUserViewable() {
      return isUserViewable;
   }

   public boolean isUserModifiable() {
      return isUserModifiable;
   }

   public boolean requiredForSynchronization() {
      return requiredForSynchronization;
   }
}
